from abc import ABC, abstractmethod
from typing import Optional, List, TYPE_CHECKING
from game.card import Card

# 使用TYPE_CHECKING避免循环导入
if TYPE_CHECKING:
    from game.character import Character

class Skill(ABC):
    """技能基类"""
    def __init__(self, name: str, description: str):
        self.name = name
        self.description = description
    
    @abstractmethod
    def can_activate(self, character: 'Character') -> bool:
        """检查技能是否可以激活"""
        pass
    
    def activate(self, character: 'Character', game=None, **kwargs) -> bool:
        """激活技能"""
        if not self.can_activate(character):
            return False
        return True
    
    def __str__(self) -> str:
        return f"{self.name}: {self.description}"

class PassiveSkill(Skill):
    """被动技能"""
    def __init__(self, name: str, description: str):
        super().__init__(name, description)
    
    def can_activate(self, character: 'Character') -> bool:
        """被动技能总是可以激活"""
        return True

class ActiveSkill(Skill):
    """主动技能"""
    def __init__(self, name: str, description: str, cooldown: int = 0):
        super().__init__(name, description)
        self.cooldown = cooldown
        self.current_cooldown = 0
    
    def can_activate(self, character: 'Character') -> bool:
        """检查技能是否可以激活"""
        return self.current_cooldown == 0
    
    def activate(self, character: 'Character', game=None, **kwargs) -> bool:
        """激活技能"""
        if super().activate(character, game, **kwargs):
            self.current_cooldown = self.cooldown
            return True
        return False
    
    def reset_cooldown(self):
        """重置冷却时间"""
        self.current_cooldown = max(0, self.current_cooldown - 1)

# 具体技能实现

class GuicaiSkill(PassiveSkill):
    """鬼才技能 - 可以用一张手牌替换判定牌"""
    def __init__(self):
        super().__init__("鬼才", "可以用一张手牌替换判定牌")
    
    def on_judge(self, character: 'Character', judge_card: Card) -> Optional[Card]:
        """在判定时触发"""
        if character.hand:
            # 选择一张手牌替换判定牌
            # 这里会与GUI交互或AI自动选择
            # 简单实现：随机选择一张手牌
            replacement_card = character.hand[0]
            character.hand.remove(replacement_card)
            character.hand.append(judge_card)
            return replacement_card
        return None

class JuyiSkill(PassiveSkill):
    """结义技能 - 每回合可以多出一张杀"""
    def __init__(self):
        super().__init__("结义", "每回合可以多出一张杀")
    
    def on_turn_start(self, character: 'Character'):
        """在回合开始时触发"""
        character.extra_attack_count = 1

class WushengSkill(PassiveSkill):
    """武圣技能 - 可以将红色手牌当作杀使用"""
    def __init__(self):
        super().__init__("武圣", "可以将红色手牌当作杀使用")
    
    def can_use_as_attack(self, character: 'Character', card: Card) -> bool:
        """检查是否可以将牌当作杀使用"""
        return card.card_type == "basic" and card.is_red()

class JiuchiSkill(PassiveSkill):
    """酒池技能 - 可以将梅花牌当作酒使用"""
    def __init__(self):
        super().__init__("酒池", "可以将梅花牌当作酒使用")
    
    def can_use_as_neutralize(self, character: 'Character', card: Card) -> bool:
        """检查是否可以将牌当作酒使用"""
        return card.suit == "梅花"

class YijiangSkill(ActiveSkill):
    """遗计技能 - 受到1点伤害后，可以摸两张牌并分配给任意角色"""
    def __init__(self):
        super().__init__("遗计", "受到1点伤害后，可以摸两张牌并分配给任意角色", 0)
    
    def on_take_damage(self, character: 'Character', damage: int, source=None, is_fire: bool = False, is_thunder: bool = False) -> int:
        """在受到伤害时触发"""
        if damage >= 1:
            # 这里会在GameEngine中实现摸牌和分配逻辑
            pass
        return damage

class JueqingSkill(PassiveSkill):
    """绝情技能 - 可以将所有手牌当作杀使用，但不能使用闪"""
    def __init__(self):
        super().__init__("绝情", "可以将所有手牌当作杀使用，但不能使用闪")
    
    def can_use_as_attack(self, character: 'Character', card: Card) -> bool:
        """检查是否可以将牌当作杀使用"""
        return True
    
    def cannot_use_defend(self, character: 'Character') -> bool:
        """检查是否不能使用闪"""
        return True

class KongchengSkill(PassiveSkill):
    """空城技能 - 没有手牌时，不能被选择为杀或决斗的目标"""
    def __init__(self):
        super().__init__("空城", "没有手牌时，不能被选择为杀或决斗的目标")
    
    def cannot_be_targeted(self, character: 'Character') -> bool:
        """检查是否不能被选择为目标"""
        return len(character.hand) == 0

# 创建常用角色的逻辑已移到game_engine.py中，避免循环导入